package com.spc.controller;

import com.alibaba.dubbo.config.annotation.Reference;

import com.spc.constant.MessageConstant;
import com.spc.constant.RedisConstant;
import com.spc.entity.PageResult;
import com.spc.entity.QueryPageBean;
import com.spc.entity.Result;
import com.spc.pojo.Member;
import com.spc.service.MemberService;
import com.spc.utils.QiniuUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.JedisPool;

import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.UUID;


/*
用户相关类
* */
//用RestController,表示在controller的基础上增减responsebody,不跳转到到视图
@RestController
@RequestMapping("/member")
public class MemberController {

    // 需要用@Referencr注解,找到对应的服务
    @Reference
    private MemberService memberService;
    //自动导入jedispool
    @Autowired
    private JedisPool jedisPool;


    /*
    分页展示用户的方法
    需要将表单提交的数据通过Requestbody,将json数据封存到queryPageBean对象中
    * */
    @RequestMapping("/querypage")
    // 给查询会员设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_QUERY')")
    public PageResult queryPage(@RequestBody QueryPageBean queryPageBean)  {
        // 1.调用memberService中的queryPage方法,将queryPageBean传递过去,返回pageResult对象
        PageResult pageResult = memberService.queryPage(queryPageBean);
        // 2.返回pageResult,并会自动将其转换为json字符串
        return pageResult;
    }

    /*
    新增用户的方法
    需要将表单提交的数据通过Requestbody,将json数据封存到member对象中
    * */
    @PostMapping("/add")
    // 给新增会员设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_ADD')")
    public Result add(@RequestBody Member member) {
        // 1.先设置member的regTime属性(注册时间)为当前时间
        member.setRegTime(new Date());
        // 2.调用memberService中的add方法,将member传递过去
        try {
            memberService.add(member);
        } catch (Exception e) {
            e.printStackTrace();
            // 3.如果调用远程服务失败,则返回的result对象为false,并设置mseeage
            return new Result(false, MessageConstant.ADD_MEMBER_FAIL);
        }
        // 4.如果没报错,则说明新增成功,返回的result对象为true
        return new Result(true, MessageConstant.ADD_MEMBER_SUCCESS);
    }



    /*
    删除会员的方法
    需要将表单提交的数据通过Requestbody,将传递过来的id的数组封存到方法的形参中
    需要将请求url的参数名与形参中数组名相同
    * */
    @DeleteMapping("/delete")
    // 给删除会员设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_DELETE')")
    // @PathVariable注解表示与{id}占位符匹配
    public Result delete(Integer[] deleteIds) {
        // 1.调用checkItemService中的delete方法,将deleteIds传递过去
        try {
            memberService.delete(deleteIds);
        } catch (Exception e) {
            e.printStackTrace();
            // 2.如果调用远程服务失败,则返回的result对象为false,并设置mseeage
            return new Result(false, MessageConstant.DELETE_MEMBER_FAIL);
        }
        // 3.如果没报错,则说明删除成功,返回的result对象为true
        return new Result(true, MessageConstant.DELETE_MEMBER_SUCCESS);
    }


    /*
   修改会员档案信息前回显数据的方法
  需要将表单提交的数据通过Requestbody,将传递过来的id封存到方法的形参中
    请求为get,所以请求参数为id,所以该形参名也为id
   * */
    @GetMapping("/findMemberById/{id}")
    // 给根据id查询会员设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_QUERY')")
    // @PathVariable注解表示与{id}占位符匹配
    public Result findMemberById(@PathVariable("id") Integer id) {
        // 1.调用checkItemService中的findCheckItemById方法,将id传递过去,得到checkitem对象
        try {
           Member member = memberService.findMemberById(id);
            // 2.如果没报错,则说明查询成功,返回的result对象为true,将得到member作为result中的data
            return new Result(true, "获取会员信息成功",member);
        } catch (Exception e) {
            e.printStackTrace();
            // 3.如果调用远程服务失败,则返回的result对象为false,并设置mseeage
            return new Result(false, "获取会员信息失败");
        }
    }

    /*
   修改(编辑)会员的方法
   需要将表单提交的数据通过Requestbody,将json数据封存到member对象中
   * */
    @PutMapping("/edit")
    // 给编辑会员设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_EDIT')")
    public Result edit(@RequestBody Member member) {
        // 1.调用memberservice中的edit方法,将member传递过去
        try {
            memberService.edit(member);
        } catch (Exception e) {
            e.printStackTrace();
            // 2.如果调用远程服务失败,则返回的result对象为false,并设置mseeage
            return new Result(false, MessageConstant.EDIT_MEMBER_FAIL);
        }
        // 3.如果没报错,则说明编辑成功,返回的result对象为true
        return new Result(true, MessageConstant.EDIT_MEMBER_SUCCESS);
    }


    /*
   分页展示会员体检报告上传信息
   需要将表单提交的数据通过Requestbody,将json数据封存到queryPageBean对象中
   * */
    @RequestMapping("/queryPageMemberReport")
    // 给查询会员设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_QUERY')")
    public PageResult queryPageMemberReport(@RequestBody QueryPageBean queryPageBean)  {
        // 1.调用memberService中的queryPage方法,将queryPageBean传递过去,返回pageResult对象
        PageResult pageResult = memberService.queryPageMemberReport(queryPageBean);
        // 2.返回pageResult,并会自动将其转换为json字符串
        return pageResult;
    }


    /*
 上传体检报告的方法
  因为已经在spring-mvc文件中定义了上传组件,所以可以用MultipartFile来接收图片
  @RequestParam("pdfFile")表示该报告的请求参数名称,需要和MultipartFile的形参相同
  (如果形参名和传递过来的name相同,则不需要该注解)
  * */
    @RequestMapping("/upload")
    public Result upload(@RequestParam("pdfFile") MultipartFile pdfFile) {
        try {
            // 1.将pdfFile文件转换成byte字节
            byte[] bytes = pdfFile.getBytes();
            // 2.在通过UUID的randomUUID随机生成唯一辨识码,toString转换为string类型的
            String str_uuid = UUID.randomUUID().toString();
            // 3.再将uuid和该pdf文件后缀拼接,得到上传后的文件名以pdf结尾
            String filename = str_uuid+".pdf";
            // 4.调用QiniuUtils的upload2Qiniu方法,bytes和filename作为参数,上传该文件
            QiniuUtils.upload2Qiniu(bytes,filename);
            // 5.上传成功后将该文件名先存储到redis中的集合中(该集合存储了上传到七牛云的提交报告)
            jedisPool.getResource().sadd(RedisConstant.MEMBER_PDF_RESOURCES,filename);
            // 6.返回result对象,并设置flag为true,message为上传成功,data为该文件的名称(用于存储到数据库)
            return new Result(true, MessageConstant.UPLOAD_SUCCESS,filename);
        } catch (IOException e) {
            e.printStackTrace();
            // 7. 如果上传失败,则返回result的falg为false,message为上传失败
            return new Result(false,"上传失败");
        }
    }


    /*
 保存会员体检报告上传
  需要将表单提交的数据通过Requestbody,将json数据封存到形参的map对象中
  * */
    @RequestMapping("/savememberupload")
    // 给保存提交报告上传设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_EDIT')")
    public Result saveMemberUpload(@RequestBody Map map) {
        try {
            // 1.调用service中的saveMemberUpload方法,将map作为参数
            memberService.saveMemberUpload(map);
            // 2.返回result对象,flag为true,message为成功
            return new Result(true,"保存成功");
        } catch (Exception e) {
            e.printStackTrace();
            // 3.如果添加失败,则返回的result对象的flag为false,message为失败
            return new Result(false,"保存失败");
        }
    }


    /*
删除会员体检报告的方法 (根据提交报告名称)
需要将表单提交的数据通过Requestbody,将传递过来的id的数组封存到方法的形参中
需要将请求url的参数名与形参中数组名相同
* */
    @DeleteMapping("/deleterepert")
    // 给删除体检报告设置权限控制注解(通过数据库中权限唯一表示符remark表示)
    @PreAuthorize("hasAuthority('USER_DELETE')")
    // @PathVariable注解表示与{id}占位符匹配
    public Result deleteRepert(String[] deleteReportPdfs) {
        // 1.调用memberService中的deleteRepert方法,将deleteIds传递过去
        try {
            memberService.deleteRepert(deleteReportPdfs);
        } catch (Exception e) {
            e.printStackTrace();
            // 2.如果调用远程服务失败,则返回的result对象为false,并设置mseeage
            return new Result(false, "删除失败");
        }
        // 3.如果没报错,则说明删除成功,返回的result对象为true
        return new Result(true, "删除成功");
    }


}
